// Keep members that are less than 32-bit adjacent to each other to conserve memory in with the default
// 4-byte alignment:
HotCriterionType mHotCriterion;
UCHAR mExistingThreads, mMaxThreads;
bool mNoSuppress; // v1.0.44: This became a per-variant attribute because it's more useful/flexible that way.
bool mMaxThreadsBuffer;
bool mRunAgainAfterFinished;
bool mEnabled; // Whether this variant has been disabled via the Hotkey command.
};
class Hotkey
{
private:
// These are done as static, rather than having an outer-class to contain all the hotkeys, because
// the hotkey ID is used as the array index for performance reasons. Having an outer class implies
// the potential future use of more than one set of hotkeys, which could still be implemented
// within static data and methods to retain the indexing/performance method:
static HookType sWhichHookNeeded;
static HookType sWhichHookAlways;
static DWORD sTimePrev;
static DWORD sTimeNow;
static HotkeyIDType sNextID;
bool Enable(HotkeyVariant &aVariant) // Returns true if the variant needed to be disabled, in which case caller should generally call ManifestAllHotkeysHotstringsHooks().
{
if (aVariant.mEnabled) // Added for v1.0.23 to greatly improve performance when hotkey is already in the right state.
return false; // Indicate that it's already enabled.
aVariant.mEnabled = true;
return true;
}
bool Disable(HotkeyVariant &aVariant) // Returns true if the variant needed to be disabled, in which case caller should generally call ManifestAllHotkeysHotstringsHooks().
{
if (!aVariant.mEnabled) // Added for v1.0.23 to greatly improve performance when hotkey is already in the right state.
return false; // Indicate that it's already disabled.
aVariant.mEnabled = false;
aVariant.mRunAgainAfterFinished = false; // ManifestAllHotkeysHotstringsHooks() won't do this unless the entire hotkey is disabled/unregistered.
return true;
}
bool EnableParent() // Returns true if the hotkey needed to be disabled, in which case caller should generally call ManifestAllHotkeysHotstringsHooks().
{
if (mParentEnabled)
return false; // Indicate that it's already enabled.
mParentEnabled = true;
return true;
}
bool DisableParent() // Returns true if the hotkey needed to be disabled, in which case caller should generally call ManifestAllHotkeysHotstringsHooks().
{
if (!mParentEnabled)
return false; // Indicate that it's already disabled.
HotkeyIDType mID; // Must be unique for each hotkey of a given thread.
HookActionType mHookAction;
char *mName; // Points to the label name for static hotkeys, or a dynamically-allocated string for dynamic hotkeys.
sc_type mSC; // Scan code. All vk's have a scan code, but not vice versa.
sc_type mModifierSC; // If mModifierVK is zero, this scan code, if non-zero, will be used as the modifier.
mod_type mModifiers; // MOD_ALT, MOD_CONTROL, MOD_SHIFT, MOD_WIN, or some additive or bitwise-or combination of these.
modLR_type mModifiersLR; // Left-right centric versions of the above.
modLR_type mModifiersConsolidatedLR; // The combination of mModifierVK, mModifierSC, mModifiersLR, modifiers
// Keep single-byte attributes adjacent to each other to conserve memory within byte-aligned class/struct:
vk_type mVK; // virtual-key code, e.g. VK_TAB, VK_LWIN, VK_LMENU, VK_APPS, VK_F10. If zero, use sc below.
vk_type mModifierVK; // Any other virtual key that must be pressed down in order to activate "vk" itself.
HotkeyTypeType mType;
#define NO_SUPPRESS_PREFIX 0x01 // Bitwise: Bit #1
#define AT_LEAST_ONE_VARIANT_HAS_TILDE 0x02 // Bitwise: Bit #2
#define AT_LEAST_ONE_VARIANT_LACKS_TILDE 0x04 // Bitwise: Bit #3
#define NO_SUPPRESS_NEXT_UP_EVENT 0x08 // Bitwise: Bit #4
#define NO_SUPPRESS_SUFFIX_VARIES (AT_LEAST_ONE_VARIANT_HAS_TILDE | AT_LEAST_ONE_VARIANT_LACKS_TILDE) // i.e. a hotkey that has variants of both types.
#define NO_SUPPRESS_STATES NO_SUPPRESS_NEXT_UP_EVENT // This is a bitwise union (currently only one item) of those of the above that represent a the key's dynamically changing state as the user types.
UCHAR mNoSuppress; // Uses the flags above. Normally 0, but can be overridden by using the hotkey tilde (~) prefix).
bool mKeybdHookMandatory;
bool mAllowExtraModifiers; // False if the hotkey should not fire when extraneous modifiers are held down.
bool mKeyUp; // A hotkey that should fire on key-up.
bool mVK_WasSpecifiedByNumber; // A hotkey defined by something like "VK24::" or "Hotkey, VK24, ..."
bool mUnregisterDuringThread; // Win9x: Whether this hotkey should be unregistered during its own subroutine (to prevent its own Send commmand from firing itself). Seems okay to apply this to all variants.
bool mIsRegistered; // Whether this hotkey has been successfully registered.
bool mParentEnabled; // When true, the individual variants' mEnabled flags matter. When false, the entire hotkey is disabled.
bool mConstructedOK;
HotkeyVariant *mFirstVariant, *mLastVariant; // v1.0.42: Linked list of variant hotkeys created via #IfWin directives.
// Make sHotkeyCount an alias for sNextID. Make it const to enforce modifying the value in only one way:
static const HotkeyIDType &sHotkeyCount;
static bool sJoystickHasHotkeys[MAX_JOYSTICKS];
static DWORD sJoyHotkeyCount;
static void AllDestructAndExit(int exit_code);
#define HOTKEY_EL_BADLABEL "1" // Set as strings so that SetFormat doesn't affect their appearance (for use with "If ErrorLevel in 5,6").
#define HOTKEY_EL_INVALID_KEYNAME "2"
#define HOTKEY_EL_UNSUPPORTED_PREFIX "3"
#define HOTKEY_EL_ALTTAB "4"
#define HOTKEY_EL_NOTEXIST "5"
#define HOTKEY_EL_NOTEXISTVARIANT "6"
#define HOTKEY_EL_WIN9X "50"
#define HOTKEY_EL_NOREG "51"
#define HOTKEY_EL_MAXCOUNT "98" // 98 allows room for other ErrorLevels to be added in between.